package com.app.brilliant.sys.controller;
import com.app.brilliant.common.api.ApiResult;
import com.app.brilliant.common.controller.BaseController;
import com.app.brilliant.common.enums.StateEnum;
import com.app.brilliant.constant.CommonConstant;
import com.app.brilliant.game.bean.BriPlan;
import com.app.brilliant.game.dto.UserPlanInfoDTO;
import com.app.brilliant.game.service.BriPlanService;
import com.app.brilliant.game.service.BriUserPlanService;
import com.app.brilliant.shiro.util.LoginUtil;
import com.app.brilliant.sys.bean.DevUser;
import com.app.brilliant.sys.bean.DevUserInfoDTO;
import com.app.brilliant.sys.service.DevUserService;
import com.app.brilliant.util.CookiesUtil;
import com.app.brilliant.util.UUIDUtil;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import java.util.Date;
import java.util.Random;
import java.util.concurrent.TimeUnit;
import com.app.brilliant.sign.constant.Constants;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

@RestController
@RequestMapping("/dev")
public class DevUserController extends BaseController {
    @Autowired
    private DevUserService devUserService;
    @Autowired
    private JavaMailSender mailSender;
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private BriUserPlanService briUserPlanService;
    @Value("${spring.mail.username}")
    private String mailFrom;
    @Autowired
    private BriPlanService briPlanService;
    private boolean checkUnLogin(){
        Long devId = LoginUtil.getLoginDevUserRedisVoId();
        if(devId == null){
            return true;
        }
        DevUser sysUser = devUserService.getById(devId);
        if(sysUser == null){
            return true;
        }
        return sysUser.getState().intValue() == StateEnum.DISABLE.getCode();
    }
    /**
     * 获取money大于0的所有bri_plan计划信息
     * @return 计划信息列表
     */
    @GetMapping("/plans/positiveMoney")
    @ApiOperation("获取money大于0的所有bri_plan计划信息")
    public ApiResult<List<BriPlan>> getBriPlansWithPositiveMoney() {
        return ApiResult.ok(briPlanService.getPlansByMoneyGreaterThan(0));
    }

    @PostMapping("/sendForgetEmailCode")
    @ApiOperation(value = "发送忘记密码邮箱验证码", notes = "发送6位邮箱验证码用于忘记密码")
    public ApiResult<Boolean> sendForgetEmailCode(@RequestParam("email") String email) {
        if (email == null || email.trim().isEmpty()) {
            return ApiResult.fail("邮箱不能为空");
        }
        if (!email.matches("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$")) {
            return ApiResult.fail("邮箱格式不正确");
        }
        String code = generateSixDigitCode();
        // 缓存到Redis
        String redisKey = String.format(Constants.NomalRedisKey.EmalKey, email);
        redisTemplate.opsForValue().set(redisKey, code, Constants.NomalIntValue.emailRedisTime, TimeUnit.SECONDS);
        // 发送邮件
        sendSimpleMail(email, Constants.NomalStr.forgetPssSub, buildMailContent(code));
        return ApiResult.ok(true, "验证码已发送");
    }

    @PostMapping("/sendRegisterEmailCode")
    @ApiOperation(value = "发送注册邮箱验证码", notes = "发送6位邮箱验证码用于注册")
    public ApiResult<Boolean> sendRegisterEmailCode(@RequestParam("email") String email, HttpServletResponse response) {
        if (email == null || email.trim().isEmpty()) {
            return ApiResult.fail("邮箱不能为空");
        }
        if (!email.matches("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$")) {
            return ApiResult.fail("邮箱格式不正确");
        }
        String code = generateSixDigitCode();
        String verifyToken = UUIDUtil.getUUID();
        // 缓存到Redis
        redisTemplate.opsForValue().set(String.format(Constants.NomalRedisKey.registerEmailKey, verifyToken), code, Constants.NomalIntValue.emailRedisTime, TimeUnit.SECONDS);
        CookiesUtil.setCookie(response, CommonConstant.VERIFY_TOKEN, verifyToken, 300);
        response.setHeader("Pragma", "No-cache");
        response.setHeader("Cache-Control", "no-cache");
        response.setDateHeader("Expire", 0);
        // 发送邮件
        sendSimpleMail(email, Constants.NomalStr.registerSub, buildMailContent(code));
        return ApiResult.ok(true, "验证码已发送");
    }

    @PostMapping("/forgetResetPassword")
    @ApiOperation(value = "忘记密码-重置", notes = "根据用户名、邮箱验证码重置新密码")
    public ApiResult<Boolean> forgetResetPassword(@RequestParam("username") String username,
            @RequestParam("newPassword") String newPassword,
            @RequestParam("email") String email,
            @RequestParam("emailCode") String emailCode) {
        if (username == null || username.trim().isEmpty()) {
            return ApiResult.fail("用户名不能为空");
        }
        if (newPassword == null || newPassword.trim().isEmpty()) {
            return ApiResult.fail("新密码不能为空");
        }
        if (email == null || email.trim().isEmpty()) {
            return ApiResult.fail("邮箱不能为空");
        }
        if (!email.matches("^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$")) {
            return ApiResult.fail("邮箱格式不正确");
        }
        if (emailCode == null || emailCode.trim().isEmpty()) {
            return ApiResult.fail("邮箱验证码不能为空");
        }
        // 校验验证码
        String redisKey = String.format(Constants.NomalRedisKey.EmalKey, email);
        Object cached = redisTemplate.opsForValue().get(redisKey);
        if (cached == null || !emailCode.equals(cached.toString())) {
            return ApiResult.fail("邮箱验证码不正确或已过期");
        }
        // 根据用户名查询用户
        DevUser devUser = devUserService.getByUsername(username);
        if (devUser == null) {
            return ApiResult.fail("用户不存在");
        }
        // 重置密码
        String salt = devUser.getSalt();
        if (salt == null || salt.trim().isEmpty()) {
            // 如果没有盐值，则生成新的盐值
            salt = com.app.brilliant.shiro.util.SaltUtil.generateSalt();
            devUser.setSalt(salt);
        }
        devUserService.updateById(devUser);
        // 使用一次后删除验证码
        redisTemplate.delete(redisKey);
        return ApiResult.ok(true, "密码重置成功");
    }

    private String generateSixDigitCode() {
        return String.format("%06d", new Random().nextInt(1000000));
    }

    private void sendSimpleMail(String to, String subject, String text) {
        SimpleMailMessage message = new SimpleMailMessage();
        message.setFrom(mailFrom);
        message.setTo(to);
        message.setSubject(subject);
        message.setText(text);
        mailSender.send(message);
    }

    private String buildMailContent(String code) {
        return "您的验证码为：" + code + "，有效期" + Constants.NomalIntValue.emailRedisTime + "秒。";
    }

    @GetMapping("/getUserInfo")
    @ApiOperation(value = "获取用户信息", notes = "获取当前登录用户的信息")
    public ApiResult<DevUserInfoDTO> getUserInfo() {
        if (checkUnLogin()) {
            return ApiResult.fail("用户未登录");
        }
        Long devId = LoginUtil.getLoginDevUserRedisVoId();
        DevUser devUser = devUserService.getById(devId);
        DevUserInfoDTO devUserInfoDTO = new DevUserInfoDTO();
        devUserInfoDTO.setId(devUser.getId());
        devUserInfoDTO.setUsername(devUser.getUserName());
        devUserInfoDTO.setEmail(devUser.getEmail());
        devUserInfoDTO.setNickname(devUser.getNickName());
        devUserInfoDTO.setState(devUser.getState());

        // 获取用户最新已支付的套餐计划
        UserPlanInfoDTO latestPaidPlan = briUserPlanService.getLatestPaidPlanInfo(devId.intValue());
        devUserInfoDTO.setLatestPaidPlan(latestPaidPlan);

        // 判断套餐是否过期
        if (latestPaidPlan != null) {
            devUserInfoDTO.setIsPlanExpired(latestPaidPlan.getEndTime().before(new Date()));
        }

        return ApiResult.ok(devUserInfoDTO, "获取用户信息成功");
    }
}